import React, { memo, forwardRef, useImperativeHandle } from 'react';
import { Form as AntForm } from 'antd';
import type { FormProps as AntFormProps, FormInstance } from 'antd';
import classNames from 'classnames';
import styles from './Form.module.css';

/**
 * 表单组件属性接口
 * @description 扩展 Ant Design Form 组件的属性
 */
export interface IFormProps extends Omit<AntFormProps, 'size'> {
  /** 表单尺寸 */
  size?: 'small' | 'middle' | 'large';
  /** 表单布局模式 */
  layout?: 'horizontal' | 'vertical' | 'inline';
  /** 是否显示必填标记 */
  requiredMark?: boolean | 'optional';
  /** 标签宽度（水平布局时有效） */
  labelWidth?: number | string;
  /** 是否禁用表单 */
  disabled?: boolean;
  /** 是否只读模式 */
  readonly?: boolean;
  /** 表单验证失败时的回调 */
  onValidationFailed?: (errorInfo: any) => void;
  /** 自定义类名 */
  className?: string;
  /** 子元素 */
  children?: React.ReactNode;
}

/**
 * 表单组件引用接口
 */
export interface IFormRef {
  /** 表单实例 */
  form: FormInstance;
  /** 提交表单 */
  submit: () => Promise<any>;
  /** 重置表单 */
  reset: () => void;
  /** 验证表单 */
  validate: () => Promise<any>;
  /** 验证指定字段 */
  validateFields: (fields?: string[]) => Promise<any>;
  /** 获取表单值 */
  getFieldsValue: () => any;
  /** 设置表单值 */
  setFieldsValue: (values: any) => void;
}

/**
 * 表单容器组件
 * @description 基于 Ant Design Form 的自定义表单容器，提供统一的样式和行为
 */
const Form = memo(forwardRef<IFormRef, IFormProps>(({
  size = 'middle',
  layout = 'vertical',
  requiredMark = true,
  labelWidth,
  disabled = false,
  readonly = false,
  onValidationFailed,
  className,
  children,
  onFinish,
  onFinishFailed,
  ...props
}, ref) => {
  const [form] = AntForm.useForm(props.form);

  // 暴露给父组件的方法
  useImperativeHandle(ref, () => ({
    form,
    submit: async () => {
      try {
        const values = await form.validateFields();
        if (onFinish) {
          await onFinish(values);
        }
        return values;
      } catch (error) {
        if (onValidationFailed) {
          onValidationFailed(error);
        }
        throw error;
      }
    },
    reset: () => {
      form.resetFields();
    },
    validate: async () => {
      return await form.validateFields();
    },
    validateFields: async (fields?: string[]) => {
      return await form.validateFields(fields);
    },
    getFieldsValue: () => {
      return form.getFieldsValue();
    },
    setFieldsValue: (values: any) => {
      form.setFieldsValue(values);
    }
  }), [form, onFinish, onValidationFailed]);

  // 处理表单提交成功
  const handleFinish = async (values: any) => {
    try {
      if (onFinish) {
        await onFinish(values);
      }
    } catch (error) {
      console.error('Form submit error:', error);
    }
  };

  // 处理表单提交失败
  const handleFinishFailed = (errorInfo: any) => {
    if (onValidationFailed) {
      onValidationFailed(errorInfo);
    }
    if (onFinishFailed) {
      onFinishFailed(errorInfo);
    }
  };

  // 获取标签列配置
  const getLabelCol = () => {
    if (layout !== 'horizontal') {
      return undefined;
    }

    if (typeof labelWidth === 'number') {
      return { span: Math.floor(labelWidth / 4) }; // 假设每个span约为4个字符宽度
    }

    if (typeof labelWidth === 'string') {
      return { style: { width: labelWidth } };
    }

    return { span: 6 }; // 默认值
  };

  // 获取包装列配置
  const getWrapperCol = () => {
    if (layout !== 'horizontal') {
      return undefined;
    }

    const labelCol = getLabelCol();
    if (labelCol?.span) {
      return { span: 24 - labelCol.span };
    }

    return { span: 18 }; // 默认值
  };

  // 组合类名
  const formClassName = classNames(
    styles.form,
    {
      [styles.small]: size === 'small',
      [styles.large]: size === 'large',
      [styles.horizontal]: layout === 'horizontal',
      [styles.vertical]: layout === 'vertical',
      [styles.inline]: layout === 'inline',
      [styles.disabled]: disabled,
      [styles.readonly]: readonly,
    },
    className
  );

  return (
    <div className={formClassName}>
      <AntForm
        form={form}
        layout={layout}
        size={size}
        requiredMark={requiredMark}
        disabled={disabled || readonly}
        labelCol={getLabelCol()}
        wrapperCol={getWrapperCol()}
        onFinish={handleFinish}
        onFinishFailed={handleFinishFailed}
        {...props}
      >
        {children}
      </AntForm>
    </div>
  );
}));

Form.displayName = 'Form';

export default Form;